/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2018-2023.
 * Description: task_struct extend support add new member avoid KABI change
 * Author: nixiaoming
 * Create: 2018-2-13
 */

#ifndef __TASK_STRUCT_EXTEND_H_
#define __TASK_STRUCT_EXTEND_H_

#include <linux/sched.h>

#ifdef CONFIG_RTOS_IDUMP
#include <linux/idump_task_extend.h>
#endif
#ifdef CONFIG_RTOS_DEBUG_SOFTLOCKUP
#include <linux/rtos_softlockup.h>
#endif
#ifdef CONFIG_RTOS_MICROSTATE_ACCT
#include <linux/msa.h>
#endif
#ifdef CONFIG_RTOS_TASKLOCK
#include <linux/tasklock.h>
#endif
#ifdef CONFIG_RTOS_RTPC_RPC
#include <linux/rtos_rtpc_rpc.h>
#endif
#ifdef CONFIG_RTOS_HKIDS
#include <linux/hkids/hkids.h>
#endif

extern struct task_struct init_task;

#ifdef CONFIG_TASK_STRUCT_EXTEND
#ifdef CONFIG_EULEROS_DFX_PERF_SCHED_TOOLS
struct task_sched_record {
	bool is_used;
	u64 avg_delay;
	u64 wakeup_at;
	int cpu;
	u8 type;
	u32 switchs;
	u64 runtime;
	pid_t wakeup_pid;
	char wakeup_comm[TASK_COMM_LEN];
	int wakeup_cpu;
	long prev_state;
};
#endif
struct vendor_task {
#ifdef CONFIG_RTOS
	/* add RTOS task_struct member here */
#ifdef CONFIG_RTOS_IDUMP
	struct idump_task_extend idump;
#endif
#ifdef CONFIG_RTOS_KBOX
	atomic_t kbox_region_conf;
#endif
#ifdef CONFIG_RTOS_HAL_SRE_PREHANDLER
	int (*sre_prehandler)(struct usr_except_args *args);
#endif
#ifdef CONFIG_RTOS_DEBUG_SOFTLOCKUP
	struct rtos_softlockup_t rtos_softlockup;
#endif
#ifdef CONFIG_RTOS_SWXN
	unsigned int swxn;
#endif
#ifdef CONFIG_RTOS_MEM_KSM_ADD
	unsigned int ksm_add_flag;
#endif
#ifdef CONFIG_RTOS_ILOCKDEP
	struct ilockdep *ilockdep_lock;
#endif
#ifdef CONFIG_RTOS_MICROSTATE_ACCT
	struct microstates *microstates;
#endif
#ifdef CONFIG_RTOS_TASKLOCK
	struct rtos_tasklock_t tasklock;
#endif
#ifdef CONFIG_HKIDS_CHK_MLTDOWN
	int segv_count;
#endif
#ifdef CONFIG_RTOS_HKIDS
	struct hkids_path_struct *hkids_path;
#endif
#ifdef CONFIG_RTOS_RTPC_RPC
	struct rpc_task_struct rpc_task;
#endif
#ifdef CONFIG_RTOS_HAL_HPVISOR_VNOTIFY
	struct chns_struct *chns;
#endif
#endif
#ifdef CONFIG_EULEROS_DFX_PERF_SCHED_TOOLS
	struct task_sched_record sched_record;
	unsigned long sched_threshold;
#endif
};


/* Adding new members to struct vendor_task
 * Do not modify struct task_struct_extend
 */
struct task_struct_extend {
	/* Do not put anything below here! */
	struct vendor_task extend;
	/* Do not put anything below here! */
	struct task_struct task;
	/* on x86, task->thread.fpu.state.xsave.extended_state_area
	 *  is u8 extended_state_area[0];  variable-sized ....
	 *
	 * WARNING: on x86, 'thread_struct' contains a variable-sized
	 * structure.  It *MUST* be at the end of 'task_struct'.
	 *
	 * so, task *MUST* be at the end of 'task_struct_extend'.
	 *
	 * Do not put anything below here!
	 */
};

extern struct vendor_task init_vendor_task;
extern int vendor_task_init(const unsigned long flags, struct task_struct *task);
extern void set_vendor_member_to_null(struct task_struct *tsk);
extern void free_task_struct_extend_member(struct task_struct *tsk);

/*
 * The caller needs to guarantee task != NULL,
 * The function does not return a failure
 */
static inline struct vendor_task *task_to_vendor_task(struct task_struct *task)
{
	struct task_struct_extend *extend;

	BUG_ON(!task);

	if (task == &init_task)
		return &init_vendor_task;

	extend = container_of(task, struct task_struct_extend, task);
	return &extend->extend;
}

#ifdef CONFIG_RTOS
/* Rename macros to avoid impact on existing RTOS features.
 * Delete the current macro alias after the rectification is complete
 */
#define task_to_rtos_task task_to_vendor_task
#define rtos_task_extend task_struct_extend
#define rtos_task_struct vendor_task
#endif

#else /* !CONFIG_TASK_STRUCT_EXTEND */

struct task_struct_extend {
	/* Do not put anything here */
	struct task_struct task;
	/* Do not put anything here */
};

static inline int vendor_task_init(const unsigned long flags, struct task_struct *task)
{
	return 0;
}

static inline void set_vendor_member_to_null(struct task_struct *tsk)
{
}

static inline void free_task_struct_extend_member(struct task_struct *tsk)
{
}
#endif /* CONFIG_TASK_STRUCT_EXTEND */
#endif /* __TASK_STRUCT_EXTEND_H_ */
